
#include "xdata.h"
#include "core.h"

#if (CONFIG_IC_TYPE == CHIP_SS888X)
#if(!CONFIG_DATA_FLASH)
static uint8_t xdata *slpram;
#endif


void xdata_init(void)
{
    /**
     * @brief 初始化data flash
     * EFR_ADR寄存器写入UDBCON地址
     * UDB控制器选择Data, 清0 RWEN
     */
#if(CONFIG_DATA_FLASH)
    DATA_FLAHS_ENABLE();
#else
    uint8_t i;
    uint8_t crc = crc8_maxim(slpram, SR_VALID_SIZE-1);

    // 指定Sleep变量起始地址
    slpram = 0x8330;

    SLEEP_RAM_ENABLE();
    // init xdata
    if (!slpram_crc_check()){
        for (i = 0; i < SR_VALID_SIZE; i++)
            slpram[i] = 0x00;
    }

#endif
}

/**
 * @brief xdata读取函数，地址范围为0x8330H~0x833FH(设置的xdata地址) 16Byte
 * 
 * @param enum_num // SR_IDX SR_IDX_Dx
 * @return int8_t 
 */
uint8_t slpram_rd_dat(uint8_t enum_num)
{
    return slpram[enum_num];
}

/**
 * @brief sleep ram 校验判断
 * 
 * @return bool: 校验是否成功
 */
bool slpram_crc_check(void)
{
    uint8_t crc = crc8_maxim(slpram, SR_VALID_SIZE-1);

    if (slpram[SR_IDX_H1] == 0x88) {
        if (crc == slpram[SR_IDX_CRC]) {
            return true;
        }
        return false;
    }

    return false;
}

/* xdata写函数，地址范围为0x8330H~0x833FH(设置的xdata地址) 16Byte*/
void slpram_wr_dat(uint8_t enum_num, uint8_t dat)
{
    slpram[SR_IDX_H1]  = 0x88;
    slpram[enum_num]  = dat;
    slpram[SR_IDX_CRC] = crc8_maxim(slpram, SR_VALID_SIZE-1);
}

void data_flash_write(uint8_t addr, uint8_t dat)
{
    IRQ_DISABLE();
    
    SET_EFR_BIT(UDBCON, DF_WR_EN);     /* EFR_ADR寄存器写入UDBCON地址 使能写*/
    WRITE_EFR_REG(EFRADR, addr);         /* EFR_ADR寄存器写入EFRADR地址 */
    WRITE_EFR_REG(EFRDAT, dat);          /* EFR_DAT寄存器写入dat */
    SET_EFR_BIT(UDBCON, DF_WR);        /* 将WR置1，激活写周期 */
    /* 等待WR清0 */
    while (READ_EFR_BIT(UDBCON, DF_WR))
        WDOG_KEEP_ALIVE();

    CLEAR_EFR_BIT(UDBCON, DF_RW_NO);      /* 清0 RWEN */

    IRQ_ENABLE();
}

uint8_t data_flash_read(uint8_t addr)
{
    uint8_t eeprom_val;
    IRQ_DISABLE();
    
    SET_EFR_BIT(UDBCON, DF_RD_EN);     /* EFR_ADR寄存器写入UDBCON地址 使能读*/
    WRITE_EFR_REG(EEPADR, addr);        /* EFR_ADR寄存器写入EFRADR地址 */
    SET_EFR_BIT(UDBCON, DF_RD);        /* 将RD置1，激活读周期 */
    /* 等待RD清0 */
    while (READ_EFR_BIT(UDBCON, DF_RD))
        WDOG_KEEP_ALIVE();

    eeprom_val = READ_EFR_REG(EFRDAT);

    CLEAR_EFR_BIT(UDBCON, DF_RW_NO);      /* 清0 RWEN */

    IRQ_ENABLE();
    
    return eeprom_val;
}

void data_flash_buf_write(uint8_t addr, uint8_t num, uint8_t *dat)
{
    uint8_t i = 0;
    IRQ_DISABLE();
    
    SET_EFR_BIT(UDBCON, DF_WR_EN);     /* EFR_ADR寄存器写入UDBCON地址 使能写*/
    while (i < num) {
        WRITE_EFR_REG(EFRADR, addr + i);        /* EFR_ADR寄存器写入EFRADR地址 */
        WRITE_EFR_REG(EFRDAT, *(dat + i));          /* EFR_DAT寄存器写入dat */
        SET_EFR_BIT(UDBCON, DF_WR);        /* 将WR置1，激活写周期 */
        /* 等待WR清0 */
        while (READ_EFR_BIT(UDBCON, DF_WR))
            WDOG_KEEP_ALIVE();
            
        i++;
    }

    CLEAR_EFR_BIT(UDBCON, DF_RW_NO);      /* 清0 RWEN */
    IRQ_ENABLE();

}

void data_flash_buf_read(uint8_t addr, uint8_t num, uint8_t *dat)
{
    uint8_t i = 0;
    IRQ_DISABLE();
    SET_EFR_BIT(UDBCON, DF_RD_EN);     /* EFR_ADR寄存器写入UDBCON地址 使能读*/

    while(i < num){
        WRITE_EFR_REG(EEPADR, addr + i);        /* EFR_ADR寄存器写入EFRADR地址 */
        SET_EFR_BIT(UDBCON, DF_RD);          /* 将RD置1，激活读周期 */
        /* 等待RD清0 */
        while (READ_EFR_BIT(UDBCON, DF_RD))
            WDOG_KEEP_ALIVE();

        *(dat + i) = READ_EFR_REG(EFRDAT);

        i++;
    }

    CLEAR_EFR_BIT(UDBCON, DF_RW_NO);      /* 清0 RWEN */
    IRQ_ENABLE();
}
#endif